import 'dart:io';

// import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/services.dart';
import 'package:flt_bmflocation/flt_bmflocation.dart';
import 'package:permission_handler/permission_handler.dart';

import '../../../extension.dart';
import '../models/flutter_baidu_location.dart';

class FclBmfLocationManager {
  // 私有构造函数
  FclBmfLocationManager._privateConstructor() {
    _init();
  }

  // 保存单例
  static final FclBmfLocationManager _instance =
      FclBmfLocationManager._privateConstructor();

  // 工厂构造函数返回单例
  factory FclBmfLocationManager() {
    return _instance;
  }

  late LocationFlutterPlugin locPlugin;

  Future<void> _init() async {}

  /// 初始化定位
  /// 设置返沪函数，用于返回定位结果
  Future<String?> initLocation() async {
    try {
      // 1、初始化定位
      locPlugin = LocationFlutterPlugin();

      String? errorTips;
      // 2、设置同意隐私协议
      bool isSuc = await locPlugin.setAgreePrivacy(true);
      print('fbmf---->setAgreePrivacyisSuc: $isSuc');
      if (!isSuc) {
        errorTips = '设置同意隐私协议失败';
        return errorTips;
      }

      if (Platform.isIOS) {
        // 3、获取AK
        String ak = await kGetBbfAk();
        // 4、设置AK
        isSuc = await locPlugin.authAK(ak);
        print('fbmf---->authAK: $isSuc');
        // 5、获取授权回调
        locPlugin.getApiKeyCallback(callback: (String result) {
          String str = result;
          print('fbmf---->getApiKeyCallback: $str');
        });
      }

      if (!isSuc) {
        errorTips = '设置AK失败';
        return errorTips;
      }
      return errorTips;
    } catch (err) {
      // ignore: unnecessary_type_check
      if (err is PlatformException) {
        return err.code;
      }
      print('fbmf---->requestPermission error: ${err.toString()}');
      rethrow;
    }
  }

  /// 检查权限
  Future<bool> checkPermission() async {
    // 前往设置弹窗
    return await requestPmsLocationWhenInUse().then((value1) {
      print('fbmf---->checkPermission: $value1');
      if (value1) {
        return true;
      }
      return false;
    });
  }

  /// 开始定位
  Future<void> startLocation({Function(FlsBaiduLocation? result, String? errStr)? block, Function(BaiduLocation? bdLocation, String? errStr)? bdBlock}) async {
    try {
      if (await locationAction()) {
        print('fbmf---->startLocation: 设置定位参数成功');
      } else {
        print('fbmf---->startLocation: 设置定位参数失败');
        return;
      }
      String? rst;
      // // 1、检查网络
      // ConnectivityResult cRst = await Connectivity().checkConnectivity();
      // if (cRst == ConnectivityResult.none) {
      //   rst = '定位失败';
      //   if (block != null) block(null, rst);
      //   if (bdBlock != null) bdBlock(null, rst);
      // }

      // 2、获取定位回调
      getLocationCallBack(block: block, bdBlock: bdBlock);

      // 3、开始定位
      bool suc = false;
      if (Platform.isIOS) {
        if (block != null) {
          suc = await locPlugin.singleLocation({'isReGeocode': true, 'isNetworkState': true});
        }
        if (bdBlock != null) {
          suc = await locPlugin.startLocation();
        }
      } else if (Platform.operatingSystem == 'ohos' || Platform.isAndroid) {
        suc = await locPlugin.startLocation();
      }
      if (!suc) {
        rst = '定位失败';
      }
      print('fbmf---->startLocationisSuc: $rst suc: $suc');
      if (block != null) block(null, rst);
      if (bdBlock != null) bdBlock(null, rst);
    } catch (e) {
      print('fbmf---->startLocation error: $e');
      rethrow;
    }
  }

  int locCount = 0;
  /// 获取定位回调
  void getLocationCallBack({Function(FlsBaiduLocation? result, String? errStr)? block, Function(BaiduLocation? bdLocation, String? errStr)? bdBlock}) {
    ///单次定位时如果是安卓可以在内部进行判断调用连续定位
    if (Platform.isIOS) {
      ///接受定位回调
      if (block != null) {
        locPlugin.singleLocationCallback(callback: (BaiduLocation result) {
          if (result.adCode == null || result.adCode == '') {
            result.adCode = result.cityCode;
          }

          if (result.errorCode == 1) {
            // 重复定位3次失败，提示用户
            if (FclBmfLocationManager().locCount >= 3) {
              FclBmfLocationManager().locCount = 0;
              if(block != null) block(null, '定位失败，请点击重试');
              return;
            }
            FclBmfLocationManager().locCount++;
            Future.delayed(const Duration(milliseconds: 500), () async {
              bool suc = await locPlugin.singleLocation(
                  {'isReGeocode': true, 'isNetworkState': true});
            });
            return;
          }

          FclBmfLocationManager().locCount = 0;
          if(block != null) block(FlsBaiduLocation.fromBaiduLocation(result), null);
          print(
              "fbmf---->seriesLocationCallback result:${result.getMap().toString()}");
        });
      }

      ///接受定位回调
      if (bdBlock != null) {
        locPlugin.seriesLocationCallback(callback: (BaiduLocation result) {
          bdBlock(result, null);
          print(
              "fbmf---->seriesLocationCallback result:${result.getMap().toString()}");
        });
      }
      
    } else if (Platform.operatingSystem == 'ohos' || Platform.isAndroid) {
      ///接受定位回调
      locPlugin.seriesLocationCallback(callback: (BaiduLocation result) {
        if (block != null) block(FlsBaiduLocation.fromBaiduLocation(result),  null);
        if (bdBlock != null) bdBlock(result, null);
        print(
            "fbmf---->seriesLocationCallback result:${result.getMap().toString()}");
        if (block == null){
          stopLocation();
        }
      });
    }
  }

  /// 停止定位
  Future<void> stopLocation() async {
    try {
      bool isSuc = await locPlugin.stopLocation();
      print('fbmf---->stopLocationisSuc: $isSuc');
    } catch (e) {
      print('fbmf---->stopLocation error: $e');
      rethrow;
    }
  }

  Future<bool> locationAction() async {
    try {
      // ohos内部没有实现，直接返回true
      if (Platform.operatingSystem == 'ohos') {
        return true;
      }
      /// 设置android端和ios端定位参数
      /// android 端设置定位参数
      /// ios 端设置定位参数
      Map iosMap = initIOSOptions().getMap();
      Map androidMap = initAndroidOptions().getMap();
      Map ohosMap = initOhosOptions().getMap();
      print('fbmf---->设置定位参数 iosMap：$iosMap androidMap:$iosMap ohosMap:$ohosMap');
      bool suc = await locPlugin.prepareLoc(androidMap, iosMap, ohosMap);
      return suc;
    } catch (e) {
      print('fbmf---->_locationAction error: $e');
      rethrow;
    }
  }

  /// 设置地图参数
  BaiduLocationAndroidOption initAndroidOptions() {
    BaiduLocationAndroidOption options = BaiduLocationAndroidOption(
        coorType: 'gcj02',
        locationMode: BMFLocationMode.hightAccuracy,
        isNeedAddress: true,
        isNeedAltitude: true,
        isNeedLocationPoiList: true,
        isNeedNewVersionRgc: true,
        isNeedLocationDescribe: true,
        openGps: true,
         scanspan: 4000,
        locationPurpose: BMFLocationPurpose.sport,
        coordType: BMFLocationCoordType.gcj02);
    return options;
  }

  BaiduLocationIOSOption initIOSOptions() {
    BaiduLocationIOSOption options = BaiduLocationIOSOption(
        coordType: BMFLocationCoordType.gcj02,
        BMKLocationCoordinateType: 'BMKLocationCoordinateTypeGCJ02',
        desiredAccuracy: BMFDesiredAccuracy.best,
        // allowsBackgroundLocationUpdates: true,
        // pausesLocationUpdatesAutomatically: false
        );
    return options;
  }

  // 设置ohos定位参数，内部没有实现
  BaiduLocationOhosOption initOhosOptions() {
    BaiduLocationOhosOption options =
        BaiduLocationOhosOption(coordType: BMFLocationCoordType.gcj02);
    return options;
  }




  /// 请求存储权限
  Future<bool> requestPmsLocation() async {
    try {
      PermissionStatus? status;
      status = await Permission.location.request();
      if (status.isGranted) {
        return true;
      }
      return false;
    } catch (e) {
      print('fdc----> requestPermission error: $e');
      return false;
    }
  }

  Future<bool> requestPmsLocationWhenInUse() async {
    try {
      return true;
      // PermissionStatus? status;
      // status = await Permission.locationWhenInUse.request();
      // if (status.isGranted) {
      //   return true;
      // }
      // return false;
    } catch (e) {
      print('fdc----> requestPermission error: $e');
      return false;
    }
  }

  Future<bool> requestPmsLocationAlways() async {
    try {
      PermissionStatus? status;
      status = await Permission.locationAlways.request();
      if (status.isGranted) {
        return true;
      }
      return false;
    } catch (e) {
      print('fdc----> requestPermission error: $e');
      return false;
    }
  }
}
